package com.business.lgh.nacos.core.utils;

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.async.DeferredResult;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;

/**
 * @author lgh
 * @version V1.0
 * @Package com.business.lgh.nacos.core.utils
 * @date 2020/6/22 7:36 下午
 */
public class WebUtils {

    /**
     * 必须参数
     * @param req
     * @param key
     * @return
     */
    public static String required(final HttpServletRequest req, final String key) {
        //获取参数
        String value = req.getParameter(key);
        if (StringUtils.isEmpty(value)){
            throw new IllegalArgumentException("params:"+key+" is required");
        }
        //TODO 要做编解码操作（因为有特殊字符$之类的）
        return value;
    }

    /**
     * 可选参数
     * @param req
     * @param key
     * @param defaultValue
     * @return
     */
    public static String optional(final HttpServletRequest req, final String key,final String defaultValue){
        String value;
        if (!req.getParameterMap().containsKey(key)||StringUtils.isEmpty(value=req.getParameter(key))){
            return defaultValue;
        }
        return value;
    }

    public static void response(HttpServletResponse response, String body, int code) throws
            IOException {
        response.setCharacterEncoding(StandardCharsets.UTF_8.name());
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(body);
        response.setStatus(code);
    }

    public static  <T> void process(DeferredResult<T> deferredResult, CompletableFuture<T> future, Function<Throwable, T> errorHandler) {

        deferredResult.onTimeout(future::join);

        future.whenComplete((t, throwable) -> {
            if (Objects.nonNull(throwable)) {
                deferredResult.setResult(errorHandler.apply(throwable));
                return;
            }
            deferredResult.setResult(t);
        });
    }

    public static  <T> void process(DeferredResult<T> deferredResult, CompletableFuture<T> future, Runnable success, Function<Throwable, T> errorHandler) {

        deferredResult.onTimeout(future::join);

        future.whenComplete((t, throwable) -> {
            if (Objects.nonNull(throwable)) {
                deferredResult.setResult(errorHandler.apply(throwable));
                return;
            }
            success.run();
            deferredResult.setResult(t);
        });
    }

}
